<?php
declare(strict_types=1);

namespace Hesb\LaravelPlus;

use Hesb\LaravelPlus\Annotation\AnnotationInterface;
use Hesb\LaravelPlus\Commands\DocsBuild;
use Hesb\LaravelPlus\Helpers\CollectHelper;
use Hesb\LaravelPlus\Router\RouteCollector;
use Hesb\LaravelPlus\Scan\ScanAnnotation;
use Illuminate\Console\Application as Artisan;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use ReflectionClass;
use ReflectionException;
use ReflectionMethod;
use Symfony\Component\Finder\Finder;

class EasyCommand
{
    public static function register(): void
    {
        $startTime = time();
        $router = new RouteCollector();
//        创建路由
        $router->init();
        //var_dump("route init");

        //1.扫描app下的类
        $helper = new CollectHelper();
        $helper->scan();
//        var_dump("扫描app下的类");

        //路由列表
        $routes = $router->getRouteList();
//        var_dump($routes);
        //扫描文件
        $methodDefinitionCollector = app(MethodDefinitionCollector::class);
        $scanAnnotation =  make(ScanAnnotation::class,[Container::getInstance(),$methodDefinitionCollector]);
        foreach ($routes as $route) {
            $controllerName = $route['controller'];
            $actionName = $route['action'];
            $scanAnnotation->scan($controllerName,$actionName);
        }

        self::load(__DIR__.'/Commands');
        $endTime = time();
        Log::info( "耗时".($endTime - $startTime)."s");
    }

    /**
     * 自动加载commands目录下的命令
     *
     * @param  array|string  $paths
     * @return void
     */
    protected static function load($paths)
    {
        $paths = array_unique(is_array($paths) ? $paths : (array) $paths);

        $paths = array_filter($paths, function ($path) {
            return is_dir($path);
        });

        if (empty($paths)) {
            return;
        }

        //初始命名空间
        $namespace = "Hesb\LaravelPlus";

        foreach ((new Finder)->in($paths)->files() as $command) {
            $command = $namespace.str_replace(
                    ['/', '.php'],
                    ['\\', ''],
                    Str::after($command->getPathname(), __DIR__)
                );

            if (is_subclass_of($command, Command::class) &&
                ! (new ReflectionClass($command))->isAbstract()) {
                Artisan::starting(function ($artisan) use ($command) {
                    $artisan->resolve($command);
                });
            }
        }
    }
}
